package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageResponse;
import com.zzyl.constant.SuperConstant;
import com.zzyl.dto.UserDto;
import com.zzyl.entity.User;
import com.zzyl.entity.UserRole;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.UserMapper;
import com.zzyl.mapper.UserRoleMapper;
import com.zzyl.service.UserService;
import com.zzyl.utils.NoProcessing;
import com.zzyl.vo.RoleVo;
import com.zzyl.vo.UserRoleVo;
import com.zzyl.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户表服务实现类
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private  UserMapper userMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;

    /**
     * 用户分页
     */
    @Override
    @Transactional
    public PageResponse<UserVo> pageQuery(Integer pageNum, Integer pageSize, UserDto userDto) {
        // 判断前端是不是查询部门
        if (StrUtil.isNotEmpty(userDto.getDeptNo())) {
            userDto.setDeptNo(NoProcessing.processString(userDto.getDeptNo()));
        }
        PageHelper.startPage(pageNum,pageSize);
        Page<UserVo> page = userMapper.pageQuery(userDto);
        // 获取每个用户的角色列表数据
        List<UserVo> userVoList = page.getResult();
        // 当前页没有用户数据直接返回
        if (CollectionUtil.isEmpty(userVoList)) {
            return PageResponse.of(page, UserVo.class);
        }
        // 获取每一个用户id
        List<Long> userIds = userVoList.stream().map(UserVo::getId).collect(Collectors.toList());
        // 当前页存在用户数据，根据用户id查询每一个用户的角色信息
        List<RoleVo> roleList = userRoleMapper.queryByUserIds(userIds);
        // 根据用户id对角色列表数据进行分组
        Map<String, List<RoleVo>> userRoleMap = roleList.stream().collect(Collectors.groupingBy(RoleVo::getUserId));
        // 为用户封装角色数据
        userVoList.stream().forEach(userVo -> {
            List<RoleVo> roleVoList = userRoleMap.getOrDefault(userVo.getId().toString(), Collections.emptyList());
            // 转换为map方便获取获取数据，将角色列表转换为 Map<角色id,角色名称>
            Map<String, String> roleMap = roleVoList.stream().collect(Collectors.toMap(roleVo -> roleVo.getId().toString(), roleVo -> roleVo.getRoleName()));
            userVo.setRoleVoIds(roleMap.keySet());
            userVo.setRoleLabels(roleMap.values().stream().collect(Collectors.toSet()));
        });
        return PageResponse.of(page, UserVo.class);
    }

    /**
     * 添加用户
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addUser(UserDto userDto) {
        // 保存用户基本信息
        User user = BeanUtil.toBean(userDto, User.class);
        user.setUsername(user.getEmail());
        // 加盐加密存储密码
        user.setPassword(BCrypt.hashpw(SuperConstant.INIT_PASSWORD));
        user.setUserType("0");
        user.setDataState(SuperConstant.DATA_STATE_0);
        user.setIsDelete(0);
        userMapper.insert(user);

        // 保存用户和职位关联信息
        Set<String> roleVoIds = userDto.getRoleVoIds();
        // 如果没有保存用户id，直接返回
        if (CollectionUtil.isEmpty(roleVoIds)) {
            return;
        }
        List<UserRole> userRoleList = roleVoIds.stream().map(roleId -> {
            UserRole userRole = new UserRole();
            userRole.setRoleId(Long.valueOf(roleId));
            userRole.setUserId(user.getId());
            userRole.setDataState(SuperConstant.DATA_STATE_0);
            return userRole;
        }).collect(Collectors.toList());
        userRoleMapper.insertBatch(userRoleList);
    }

    /**
     * 用户修改
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modifyUser(UserDto userDto) {
        User bean = BeanUtil.toBean(userDto, User.class);
        User user = userMapper.selectByPrimaryKey(userDto.getId());
        if(user == null){
            throw new BaseException(BasicEnum.PARAMETER_MISSING);
        }
        //修改用户表基本信息
        userMapper.updateByPrimaryKeySelective(bean);
        if(CollectionUtil.isNotEmpty(userDto.getRoleVoIds())){
            // 先删除旧的用户角色信息
            userRoleMapper.deleteUserRoleById(userDto.getId());
            // 再批量添加新的用户角色信息
            Set<String> roleVoIds = userDto.getRoleVoIds();
            List<UserRole> collect = roleVoIds.stream().map(roleId -> {
                UserRole userRole = new UserRole();
                userRole.setUserId(bean.id);
                userRole.setRoleId(Long.valueOf(roleId));
                userRole.setDataState(bean.getDataState());
                return userRole;
            }).collect(Collectors.toList());
            userRoleMapper.insertBatch(collect);
        }
        if(!StrUtil.equals(user.getEmail(), userDto.getEmail()) || !StrUtil.equals(userDto.getDataState(), user.getDataState())){
            throw new BaseException(BasicEnum. LOGIN_LOSE_EFFICACY);
        }
    }

    /**
     * 启用/禁用
     */
    @Override
    public void modifyUserStatus(String id, String status) {
        userMapper.modifyUserStatus(Long.valueOf(id),status);
    }

    /**
     * 删除用户
     */
    @Override
    public void deleteUser(String userIds) {
        User user = userMapper.selectByPrimaryKey(Long.valueOf(userIds));
        if(StrUtil.equals(user.getDataState(), "0")){
            throw new BaseException(BasicEnum.ENABLED_CANNOT_DELETED);
        }
        userMapper.is_delete(Long.valueOf(userIds));
    }

    /**
     * 重置密码
     */
    @Override
    public void resetPassword(String userId) {
        User user = new User();
        user.setId(Long.valueOf(userId));
        // 加盐加密存储密码
        user.setPassword(BCrypt.hashpw(SuperConstant.INIT_PASSWORD));
        userMapper.resetPassword(user);
    }

    /**
     * 用户列表
     */
    @Override
    public User userList(String realName) {
        User user = userMapper.userList(realName);
        return user;
    }
}
